import React, { useState, useEffect, useRef } from 'react';
import { Button, Upload, message, Progress, Card, Tabs, Divider, Alert } from 'antd';
import { UploadOutlined, SoundOutlined, DragOutlined, FileAddOutlined } from '@ant-design/icons';
import type { UploadFile, UploadProps, RcFile } from 'antd/es/upload/interface';
import axios from 'axios';
import styles from './index.module.less';
// 导入配置
import { API_CONFIG } from '../../../config';
import { useRecoilState } from 'recoil';
import { mesh1State } from '../../../store';

// 使用配置中的 BASE_URL 而不是 process.env
const API_BASE_URL = API_CONFIG.BASE_URL;

interface UploadResult {
  message: string;
  output_path: string;
  process_time: string;
  status: 'success' | 'error';
}

const { TabPane } = Tabs;

const AudioUpload: React.FC = () => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState<boolean>(false);
  const [uploadProgress, setUploadProgress] = useState<number>(0);
  const [uploadResult, setUploadResult] = useState<UploadResult | null>(null);
  const [rawFile, setRawFile] = useState<RcFile | null>(null);
  const [mesh1, setMesh1] = useRecoilState(mesh1State);
  
  // npy上传相关状态
  const [npyFileList, setNpyFileList] = useState<UploadFile[]>([]);
  const [npyRawFile, setNpyRawFile] = useState<RcFile | null>(null);
  const [npyUploading, setNpyUploading] = useState<boolean>(false);
  const [npyUploadProgress, setNpyUploadProgress] = useState<number>(0);
  
  // 拖动控制相关状态
  const [isDragging, setIsDragging] = useState(false);
  const [position, setPosition] = useState({ x: window.innerWidth - 350, y: 100 });
  const [startPos, setStartPos] = useState({ x: 0, y: 0 });
  const audioUploadRef = useRef<HTMLDivElement>(null);

  const [isFirstTimeLoading, setIsFirstTimeLoading] = useState<boolean>(false);
  const [processingTip, setProcessingTip] = useState<string | null>(null);

  const handleUpload = async () => {
    if (fileList.length === 0 || !rawFile) {
      message.error('请先选择音频文件');
      return;
    }

    const formData = new FormData();
    formData.append('file', rawFile);
    formData.append('dataset', 'vocaset'); // 默认使用vocaset数据集

    setUploading(true);
    setUploadProgress(0);
    setUploadResult(null);
    setProcessingTip('正在上传和处理音频...');

    try {
      // 设置首次加载提示
      setIsFirstTimeLoading(true);
      setProcessingTip('首次处理可能需要较长时间，正在加载AI模型...');
      
      // 使用完整URL进行API请求
      const response = await axios.post(`${API_BASE_URL}/wav2npy`, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        // 支持跨域凭证
        withCredentials: false, // 根据需要设置为true，如果后端需要接收cookie
        onUploadProgress: (progressEvent) => {
          if (progressEvent.total) {
            const percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            setUploadProgress(percentCompleted);
          }
        },
      });

      // 检查是否是首次加载
      if (response.data.first_time_load) {
        message.success('模型已成功加载，后续处理将更快!');
      }

      if (response.data.status === 'success') {
        setIsFirstTimeLoading(false);
        setProcessingTip(null);
        message.success('音频处理成功！');
        setUploadResult(response.data);
        if (response.data.mesh_data) {
          setMesh1(response.data.mesh_data);
          message.success('音频处理成功，3D模型已更新');
        } else {
          message.warning('音频处理成功，但未返回mesh数据');
        }
      } else {
        setIsFirstTimeLoading(false);
        setProcessingTip(null);
        message.error(`处理失败: ${response.data.message}`);
      }
    } catch (error: any) {
      console.error('上传错误:', error);
      setIsFirstTimeLoading(false);
      setProcessingTip(null);
      message.error(
        error.response?.data?.message || '上传失败，请检查网络连接或服务器地址'
      );
    } finally {
      setUploading(false);
    }
  };

  // 处理NPY文件上传
  const handleNpyUpload = async () => {
    if (npyFileList.length === 0 || !npyRawFile) {
      message.error('请先选择NPY文件');
      return;
    }

    const formData = new FormData();
    formData.append('file', npyRawFile);

    setNpyUploading(true);
    setNpyUploadProgress(0);

    try {
      // 使用完整URL进行API请求
      const response = await axios.post(`${API_BASE_URL}/upload-npy`, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        withCredentials: false,
        onUploadProgress: (progressEvent) => {
          if (progressEvent.total) {
            const percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            setNpyUploadProgress(percentCompleted);
          }
        },
      });

      if (response.data.status === 'success') {
        message.success('NPY文件上传成功！');
        // 将返回的mesh数据设置到recoil状态
        if (response.data.mesh_data) {
          setMesh1(response.data.mesh_data);
          message.success('3D模型已更新');
        } else {
          message.warning('文件上传成功，但未返回有效mesh数据');
        }
      } else {
        message.error(`上传失败: ${response.data.message}`);
      }
    } catch (error: any) {
      console.error('上传错误:', error);
      message.error(
        error.response?.data?.message || 'NPY文件上传失败，请检查网络连接或服务器地址'
      );
    } finally {
      setNpyUploading(false);
    }
  };

  const props: UploadProps = {
    onRemove: () => {
      setFileList([]);
      setRawFile(null);
      setUploadResult(null);
    },
    beforeUpload: (file) => {
      // 验证文件类型
      const isWav = file.type === 'audio/wav';
      if (!isWav) {
        message.error('只能上传WAV格式的音频文件!');
        return Upload.LIST_IGNORE;
      }

      // 验证文件大小 (限制为50MB)
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        message.error('音频文件必须小于50MB!');
        return Upload.LIST_IGNORE;
      }

      // 保存原始文件引用
      setRawFile(file);
      setFileList([
        {
          uid: file.uid,
          name: file.name,
          size: file.size,
          type: file.type,
          percent: 0,
          status: 'done',
        }
      ]);
      return false; // 阻止自动上传
    },
    fileList,
    accept: '.wav',
  };

  // NPY文件上传配置
  const npyProps: UploadProps = {
    onRemove: () => {
      setNpyFileList([]);
      setNpyRawFile(null);
    },
    beforeUpload: (file) => {
      // 验证文件扩展名
      const isNpy = file.name.toLowerCase().endsWith('.npy');
      if (!isNpy) {
        message.error('只能上传NPY格式的文件!');
        return Upload.LIST_IGNORE;
      }

      // 验证文件大小 (限制为50MB)
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        message.error('文件必须小于50MB!');
        return Upload.LIST_IGNORE;
      }

      // 保存原始文件引用
      setNpyRawFile(file);
      setNpyFileList([
        {
          uid: file.uid,
          name: file.name,
          size: file.size,
          type: file.type,
          percent: 0,
          status: 'done',
        }
      ]);
      return false; // 阻止自动上传
    },
    fileList: npyFileList,
    accept: '.npy',
  };

  const playAudio = () => {
    if (rawFile) {
      const audio = new Audio(URL.createObjectURL(rawFile));
      audio.play();
    }
  };

  // 拖动开始时的处理函数
  const handleMouseDown = (e: React.MouseEvent) => {
    if (e.button !== 0) return; // 只处理左键点击
    setIsDragging(true);
    setStartPos({ 
      x: e.clientX - position.x,
      y: e.clientY - position.y
    });
    e.preventDefault();
  };

  // 处理拖动中
  const handleMouseMove = (e: MouseEvent) => {
    if (!isDragging) return;
    
    setPosition({
      x: e.clientX - startPos.x,
      y: e.clientY - startPos.y
    });
  };

  // 处理拖动结束
  const handleMouseUp = () => {
    setIsDragging(false);
  };

  // 添加和移除全局事件监听器
  useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, startPos]);

  return (
    <div 
      className={styles.audioUploadFloating}
      style={{ 
        left: `${position.x}px`, 
        top: `${position.y}px`,
        cursor: isDragging ? 'grabbing' : 'auto'
      }}
      ref={audioUploadRef}
    >
      <div className={styles.dragHandle} onMouseDown={handleMouseDown}>
        <DragOutlined /> 上传与处理
      </div>
      <div className={styles.audioUploadContainer}>
        {/* 首次加载提示 */}
        {isFirstTimeLoading && (
          <Alert
            message="模型加载中"
            description="首次处理需要加载AI模型，可能需要较长时间(约1-2分钟)，请耐心等待。后续处理将会更快。"
            type="info"
            showIcon
            className={styles.modelLoadingAlert}
          />
        )}

        <Tabs defaultActiveKey="audio">
          <TabPane tab="音频上传" key="audio">
            <Upload {...props} listType="picture">
              <Button icon={<UploadOutlined />}>选择WAV文件</Button>
            </Upload>

            <div className={styles.buttonGroup}>
              <Button
                type="primary"
                onClick={handleUpload}
                disabled={fileList.length === 0}
                loading={uploading}
              >
                {uploading ? (processingTip || '处理中...') : '上传并处理'}
              </Button>

              <Button
                onClick={playAudio}
                disabled={fileList.length === 0}
                icon={<SoundOutlined />}
              >
                试听
              </Button>
            </div>

            {uploading && (
              <Progress
                percent={uploadProgress}
                status="active"
                className={styles.progressBar}
              />
            )}

            {uploadResult && (
              <Card
                title="处理结果"
                className={styles.resultCard}
                size="small"
              >
                <p>状态: {uploadResult.status}</p>
                <p>消息: {uploadResult.message}</p>
                <p>处理时间: {uploadResult.process_time}</p>
                <p>输出路径: {uploadResult.output_path}</p>
              </Card>
            )}
          </TabPane>
          
          <TabPane tab="NPY上传" key="npy">
            <Upload {...npyProps} listType="picture">
              <Button icon={<FileAddOutlined />}>选择NPY文件</Button>
            </Upload>

            <div className={styles.buttonGroup}>
              <Button
                type="primary"
                onClick={handleNpyUpload}
                disabled={npyFileList.length === 0}
                loading={npyUploading}
              >
                {npyUploading ? '上传中...' : '上传并渲染'}
              </Button>
            </div>

            {npyUploading && (
              <Progress
                percent={npyUploadProgress}
                status="active"
                className={styles.progressBar}
              />
            )}
            
            <div className={styles.description}>
              <p>说明: 直接上传预生成的NPY文件，系统将直接渲染3D模型</p>
            </div>
          </TabPane>
        </Tabs>
      </div>
    </div>
  );
};

export default AudioUpload;
